#pragma once

#include<iostream>
#include<string>
#include<functional>
#include<pthread.h>
#include<cstring>
#include<cerrno>

#include"Sock.hpp"
#include"err.hpp"
#include"log.hpp"

namespace ns_server
{
    const uint16_t defaultport=8888;
    using func_t = std::function<std::string(std::string&)>;

    class HttpServer;
    //线程信息结构体
    class ThreadDate
    {
    public:
        ThreadDate(int sock,std::string clientIp,uint16_t clientPort,HttpServer*h)
        :_sock(sock),_clientIp(clientIp),_clientPort(clientPort),hsvr(h)
        {}

        ~ThreadDate(){}
    public:
    int _sock;//数据通信的套接字
    std::string _clientIp;//客户IP
    uint16_t _clientPort;//客户端口号
    HttpServer* hsvr;//回调指针
    };

    class HttpServer
    {
    public:
        HttpServer(func_t func,uint16_t port=defaultport):_port(port),_func(func)
        {}
        //初始化服务器
        void InitServer()
        {
            _listensock.Socket();//创建套接字
            _listensock.Bind(_port);//绑定
            _listensock.Listen();//监听
        }
        //启动服务器
        void Start()
        {
            while(true)
            {
                std::string clientIp;
                uint16_t clientPort;
                int sock=_listensock.Accept(&clientIp,&clientPort);
                if(sock<0)
                {
                    logMessage(Warning,"accept fail,%s,errno:%d",strerror(errno),errno);
                    continue;
                }
                //多线程
                ThreadDate * td=new ThreadDate(sock,clientIp,clientPort,this);
                pthread_t pid;
                pthread_create(&pid,nullptr,ThreadRoutine,td);
            }
        }
        //启动函数
        static void* ThreadRoutine(void*args)
        {
            //线程分离
            pthread_detach(pthread_self());
            //回调
            ThreadDate*td=static_cast<ThreadDate*>(args);
            td->hsvr->HandlerHttpRequest(td->_sock);
            //关闭套接字
            close(td->_sock);
            delete td;
            return nullptr;
        }
        //IO函数
        void HandlerHttpRequest(int sock)
        {
            std::string request;
            char buffer[4096];
            int n=recv(sock,buffer,sizeof(buffer)-1,0);
            if(n>0)//读取成功
            {
                buffer[n]='\0';
                request=buffer;
                //业务处理
                std::string responce=_func(request);
                //返回响应
                send(sock,responce.c_str(),responce.size(),0);
            }
            else
                logMessage(Info,"client quit...");
        }

        ~HttpServer(){}
    private:
    uint16_t _port;//端口号
    Sock _listensock;//监听套接字
    func_t _func;//客户处理函数
    };
}